package cn.hpclub.server.controller.admin;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.aop.Before;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.render.JsonRender;
import com.jfinal.upload.UploadFile;

import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.model.MemberOrg;
import cn.hpclub.server.model.MemberWhite;
import cn.hpclub.server.service.MemberWhiteService;
import cn.hpclub.server.util.excel.ExcelLogs;
import cn.hpclub.server.util.excel.ExcelUtil;

// @API("/ProductServer/Product")
public class MemberWhiteController extends BaseAdminController<MemberWhite>{
    private static final Logger logger                 = LoggerFactory.getLogger(MemberWhiteController.class);
    private static final String HTML_MEMBER_WHITE_LIST = "/admin/member_white.tpl";
    private static final String URL_TEMPLATE           = "/template/admin/file/白名单导入模版-大掌柜.xls";
    private static final String WHITE_USERNAME         = "白名单账号";
    private static final String CMCC_USERNAME          = "中移账号";
    private static final String USER                   = "使用者姓名";

    @Before(Tx.class)
    public void list(){
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo();;
        findByPageForSearch("select member_white_list.id as id,member_white_list.username as username,member_white_list.cmcc_user as cmcc_user,memOrg.name as name,memOrg.emp_code as emp_code,memOrg.member_type,orgTable.NumCode as org_num_code,orgTable.DisplayName as org_name,member_white_list.enabled as enabled",
                            new MemberWhiteService().service.getSqlExceptSelect(searchInfo));
        setAttrs(searchInfo);
        render(HTML_MEMBER_WHITE_LIST);
    }

    @Before(Tx.class)
    public void upload(){
        String resultMsg = null;
        int status = 1;
        try{
            resultMsg = importMemberWhite();
        }
        catch(FileNotFoundException e){
            e.printStackTrace();
            resultMsg = "文件不存在";
            status = 0;
        }
        catch(OfficeXmlFileException | EncryptedDocumentException | InvalidFormatException e){
            e.printStackTrace();
            resultMsg = "格式错误，请上传excel 2003/2007格式文件";
            status = 0;
        }
        catch(Exception e){
            e.printStackTrace();
            resultMsg = "服务器处理故障";
            status = 0;
        }
        finally{
            Map<String, Object> jsonMap = buildUploadReturnMsg(status, resultMsg);
            render(new JsonRender(jsonMap).forIE());
        }
    }

    /**
     * @Title: importMemberWhite
     * @Description:TODO
     * @return
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     * @throws Exception
     *             String
     */

    private String importMemberWhite() throws FileNotFoundException, InvalidFormatException, Exception{
        int successCount = 0;
        int totalSize = 0;
        UploadFile uf = getFile();
        InputStream inputStream = null;
        inputStream = new FileInputStream(uf.getFile());

        ExcelLogs logs = new ExcelLogs();
        Collection<Map> importExcel = ExcelUtil.importExcel(Map.class, inputStream, "yyyy/MM/dd HH:mm:ss", logs, 0);
        totalSize = importExcel.size();
        String errorMsg = "";
        int i = 1;
        for(Map<?, ?> m : importExcel){
            String itemErrorMsg = saveorUpdateData(m, i);
            if(itemErrorMsg == null){
                successCount++;
            } else{
                errorMsg += itemErrorMsg;
            }
            i++;
        }
        int failedCount = totalSize - successCount;
        if((failedCount > 0) && (errorMsg.length() > 200)){
            errorMsg = errorMsg.substring(0, 200) + "\r\n。。。。。。";
        }
        return "成功：" + successCount + "条," + "失败：" + failedCount + "条。"
                + ((failedCount > 0 || (totalSize == 0)) ? errorMsg : "");
    }

    public void template(){
        renderFile(URL_TEMPLATE);
    }

    @Before(Tx.class)
    public void delete(){
        // 仅删除白名单关系表
        deleteById(Constant.Table.MEMBER_WHITE);
    }

    @Before(Tx.class)
    public void changeStatus(){
        String id = getPara("id");
        String targetStatus = getPara("target_status");
        String sql = "";
        if(targetStatus.equalsIgnoreCase("1")){
            sql = "update " + Constant.Table.MEMBER_WHITE + " set enabled = 1 where id=?";
        } else{
            sql = "update " + Constant.Table.MEMBER_WHITE + " set enabled = 0 where id=?";
        }
        boolean success = Db.update(sql, id) > 0;
        if(success){
            if(targetStatus.equalsIgnoreCase("1")){
                ajaxJsonSuccessMessage("已启用");
            } else{
                ajaxJsonSuccessMessage("已停用");
            }
        } else{
            ajaxJsonErrorMessage("操作失败");
        }

    }

    String getString(String fullString, int maxLen){
        // 为空
        if(StringUtils.isBlank(fullString)){
            return "";
        }

        // 为null
        if("null".equalsIgnoreCase(fullString)){
            return "";
        }

        if(fullString.length() > maxLen){
            return fullString.substring(0, maxLen);
        }

        // 长度小于，都直接返回
        return fullString;
    }

    public boolean isMobileNO(String mobiles){
        Pattern p = Pattern.compile(Constant.Regex.MOBILE);
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    /**
     * @Title: saveorUpdateData
     * @Description:将一条excel数据解析保存到数据。
     * @param data，一条excel数据
     * @param i，第几条，用于合成errormsg
     * @return String 保存成功，返回null。保存失败，返回errorMsg.
     */
    private String saveorUpdateData(Map<?, ?> data, int i) throws Exception{
        String errorMsg = "";
        if(!validImportExcelCellData(data)){
            errorMsg = "\r\n第" + i + "条：白名单账号、中移账号、使用者姓名不能为空";
            return errorMsg;
        }
        // 两个手机号均去掉空格
        String whiteMobile = ExcelUtil.removeSpace(String.valueOf(data.get(WHITE_USERNAME)));
        if(!isMobileNO(whiteMobile)){
            errorMsg = "\r\n第" + i + "条：白名单账号手机号码格式不正确";
            return errorMsg;
        }
        String cmccMobile = ExcelUtil.removeSpace(String.valueOf(data.get(CMCC_USERNAME)));
        if(!isMobileNO(cmccMobile)){
            errorMsg = "\r\n第" + i + "条：中移账号手机号码格式不正确";
            return errorMsg;
        }
        String user = getString(String.valueOf(data.get(USER)), MemberOrg.MAX_NAME_LEN);

        boolean ifCmccMobileExist = MemberOrg.dao.isExistMemberOrg(cmccMobile);
        if(ifCmccMobileExist){
            updateWhiteMember(whiteMobile, cmccMobile, user);
            // 写member_white_list
            updateWhiteList(whiteMobile, cmccMobile, user);
            // 成功返回null
            return null;
        } else{
            // cmcc账号不存在
            errorMsg = "\r\n第" + i + "条：中移账号" + cmccMobile + "不存在";
            return errorMsg;
        }

    }

    /**
     * @Title: updateWhiteList
     * @Description:TODO
     * @param whiteMobile
     * @param cmccMobile
     * @param user
     *            void
     */

    private void updateWhiteList(String whiteMobile, String cmccMobile, String user){
        MemberWhite white = MemberWhite.dao.getMemberWhiteRecord(whiteMobile);
        if(white == null){
            // 不存在，则建立白名单-cmcc关联
            white = getModel(MemberWhite.class);
            white.set(MemberWhite.USERNAME, whiteMobile);
            white.set(MemberWhite.CMCC_USER, cmccMobile);
            white.set(MemberWhite.REMARK, user);
            white.set(MemberWhite.ENABLED, 1);
            white.save();

        } else{
            // 存在，则更新白名单-cmcc关联关系
            white.set(MemberWhite.USERNAME, whiteMobile);
            white.set(MemberWhite.CMCC_USER, cmccMobile);
            white.set(MemberWhite.REMARK, user);
            white.set(MemberWhite.ENABLED, 1);
            white.update();
        }
    }

    /**
     * @Title: updateWhiteUser
     * @Description:TODO
     * @param whiteMobile
     * @param cmccMobile
     * @param user
     *            void
     */

    private void updateWhiteMember(String whiteMobile, String cmccMobile, String user){
        MemberOrg white = MemberOrg.dao.getMemberOrgbyUserName(whiteMobile);
        MemberOrg cmcc = MemberOrg.dao.getMemberOrgbyUserName(cmccMobile);
        Date now = new Date(new Date().getTime());
        if(white == null){
            // 若不存在，则新增员工
            white = getModel(MemberOrg.class);
            white.set(MemberOrg.NAME, user);
            white.set(MemberOrg.EMP_CODE, cmcc.getStr(MemberOrg.EMP_CODE));
            white.set(MemberOrg.USER_NAME, whiteMobile);
            white.set(MemberOrg.NICKNAME, whiteMobile);
            white.set(MemberOrg.MOBILE, whiteMobile);
            white.set(MemberOrg.MEMBER_TYPE, cmcc.getInt(MemberOrg.MEMBER_TYPE));
            white.set(MemberOrg.IMPORT_DESC, "白名单导入，使用者:" + user);
            white.set(MemberOrg.ORG_ID, cmcc.getInt(MemberOrg.ORG_ID));
            String pwd = whiteMobile.substring(whiteMobile.length() - 6, whiteMobile.length());
            white.set(MemberOrg.PASSWORD, DigestUtils.md5Hex(pwd));
            white.set(MemberOrg.REG_TIME, now);
            white.set(MemberOrg.MODI_DATE, now);
            white.set(MemberOrg.IS_DELETED, 0);
            white.save();
        } else{
            // 若white已经存在，则 修改员工信息,激活
            white.set(MemberOrg.NAME, user);
            white.set(MemberOrg.EMP_CODE, cmcc.getStr(MemberOrg.EMP_CODE));
            white.set(MemberOrg.USER_NAME, whiteMobile);
            white.set(MemberOrg.MOBILE, whiteMobile);
            white.set(MemberOrg.NICKNAME, whiteMobile);

            white.set(MemberOrg.MEMBER_TYPE, cmcc.getInt(MemberOrg.MEMBER_TYPE));
            white.set(MemberOrg.IMPORT_DESC, "白名单导入，使用者:" + user);
            white.set(MemberOrg.ORG_ID, cmcc.getInt(MemberOrg.ORG_ID));
            String pwd = whiteMobile.substring(whiteMobile.length() - 6, whiteMobile.length());
            white.set(MemberOrg.PASSWORD, DigestUtils.md5Hex(pwd));
            white.set(MemberOrg.MODI_DATE, now);

            // 对于已经软删除的数据，重新导入时，更新数据并重新激活。并记录更新时间.
            white.set(MemberOrg.IS_DELETED, 0);
            white.set(MemberOrg.ENABLED, 1);
            white.update();
        }
    }

    private boolean validImportExcelCellData(Map<?, ?> data){
        String whiteMobile = String.valueOf(data.get(WHITE_USERNAME));
        String cmccMobile = String.valueOf(data.get(CMCC_USERNAME));
        String user = String.valueOf(data.get(USER));
        if(StringUtils.isBlank(whiteMobile) || "null".equalsIgnoreCase(whiteMobile) || StringUtils.isBlank(cmccMobile)
                || "null".equalsIgnoreCase(cmccMobile) || StringUtils.isBlank(user) || "null".equalsIgnoreCase(user)){
            logger.error("validImportExcelCellData data error");
            return false;
        }
        return true;
    }

}